package com.study.english.service.impl;

import cn.hutool.core.annotation.MirrorFor;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.study.english.context.SecurityContextHolder;
import com.study.english.pojo.vo.SysUserStudyTimeVo;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

import org.springframework.beans.BeanUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.study.english.domain.SysUserStudyTime;
import com.study.english.service.ISysUserStudyTimeService;
import com.study.english.mapper.SysUserStudyTimeMapper;
import org.springframework.stereotype.Service;

/**
 * @author wf
 * @description 针对表【sys_user_study_time(人员学习截至时间)】的数据库操作Service实现
 * @createDate 2024-03-11 15:56:34
 */
@Service
public class SysUserStudyTimeServiceImpl extends ServiceImpl<SysUserStudyTimeMapper, SysUserStudyTime>
        implements ISysUserStudyTimeService {

    @Autowired
    private ISysUserStudyTimeService sysUserStudyTimeService;


    @Override
    public void addSysUserStudyTime(SysUserStudyTimeVo sysUserStudyTimeVo) {
        SysUserStudyTime sysUserStudyTime = new SysUserStudyTime();
        BeanUtils.copyProperties(sysUserStudyTimeVo, sysUserStudyTime);
        sysUserStudyTime.setIsDelete(0);
        sysUserStudyTime.setCreateTime(new Date());
        sysUserStudyTimeService.save(sysUserStudyTime);
    }

    @Override
    public IPage<SysUserStudyTimeVo> getSysUserStudyTimePageList(IPage<SysUserStudyTimeVo> page, SysUserStudyTimeVo sysUserStudyTimeVo) {
        return this.baseMapper.getSysUserStudyTimePageList(page, sysUserStudyTimeVo);
    }


    @Override
    public List<SysUserStudyTimeVo> getSysUserStudyTimeList(SysUserStudyTimeVo sysUserStudyTimeVo) {
        return this.baseMapper.getSysUserStudyTimeList(sysUserStudyTimeVo);

    }

    @Override
    public SysUserStudyTime getSysUserStudyTimeById(String id) {
        return sysUserStudyTimeService.getById(id);
    }


    @Override
    public void delSysUserStudyTime(String id) {
        sysUserStudyTimeService.removeById(id);
    }


    @Override
    public Boolean checkIsNotWatchVideo() {
        Date date = new Date();
        Boolean boo = false;
        Long userId = SecurityContextHolder.getUserId();
        List<SysUserStudyTime> sysUserStudyTimeList = sysUserStudyTimeService.list(new QueryWrapper<SysUserStudyTime>().ge("end_time", date).le("start_time", date).eq("user_id", userId));
        if (sysUserStudyTimeList != null && sysUserStudyTimeList.size() != 0) {
            boo = true;
        }
        return boo;
    }

    @Override
    public Map<String, Object> lastSevenDay() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Long userId = SecurityContextHolder.getUserId();
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -10);
        Date startTime = cal.getTime();
        String startStr = simpleDateFormat.format(startTime);
        Map<String, Map<String, String>> mapDay = new HashMap<>();
        List<SysUserStudyTime> sysUserStudyTimeList = sysUserStudyTimeService.list(new QueryWrapper<SysUserStudyTime>().eq("user_id", userId).apply(" date_format( start_time ,'%Y-%m-%d' ) >='" + startStr + "'"));
        for (SysUserStudyTime vo : sysUserStudyTimeList) {
            Date startTime1 = vo.getStartTime();
            Date endTime = vo.getEndTime();
            String startTimeStr = simpleDateFormat.format(startTime1);
            Long watchTime = (endTime.getTime() - startTime1.getTime()) / (1000 * 60);
            if (mapDay.get(startTimeStr) == null) {
                Map<String, String> map = new HashMap<>();
                map.put("day", startTimeStr);
                map.put("watchTime", watchTime.toString());
                mapDay.put(startTimeStr, map);
            } else {
                Map<String, String> map = mapDay.get(startTimeStr);
                String watchTimeStr = map.get("watchTime");
                Long watchTimeNew = Long.parseLong(watchTimeStr) + watchTime;
                map.put("watchTime", watchTimeNew.toString());
            }
        }
        List<String> xAxisData = new ArrayList<>();
        List<String> seriesData = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap();
        for (int i = 0; i < 11; i++) {
            Date time = cal.getTime();
            String timeSort = simpleDateFormat.format(time);
            Map<String, String> stringStringMap = mapDay.get(timeSort);
            String num = "0";
            if (stringStringMap != null) {
                num = stringStringMap.get("watchTime");
            }
            seriesData.add(num);
            xAxisData.add(timeSort);
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        resultMap.put("xAxis", xAxisData);
        resultMap.put("series", seriesData);
        return resultMap;
    }

    @Override
    public Map<String, Object> weekThreeWatchTime() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Long userId = SecurityContextHolder.getUserId();
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -14);
        Date startTime = cal.getTime();
        DateTime weekStartTime = DateUtil.beginOfWeek(startTime);
        String yearStr = simpleDateFormat.format(weekStartTime);
        Map<String, Map<String, String>> mapDay = new HashMap<>();
        List<SysUserStudyTime> sysUserStudyTimeList = sysUserStudyTimeService.list(new QueryWrapper<SysUserStudyTime>().eq("user_id", userId).apply(" date_format( start_time ,'%Y-%m-%d' ) >='" + yearStr + "'"));
        for (SysUserStudyTime vo : sysUserStudyTimeList) {
            Date startTime1 = vo.getStartTime();
            Date endTime = vo.getEndTime();
            String startTimeStr = simpleDateFormat.format(startTime1);
            Long watchTime = (endTime.getTime() - startTime1.getTime());
            if (mapDay.get(startTimeStr) == null) {
                Map<String, String> map = new HashMap<>();
                map.put("day", startTimeStr);
                map.put("watchTime", watchTime.toString());
                mapDay.put(startTimeStr, map);
            } else {
                Map<String, String> map = mapDay.get(startTimeStr);
                String watchTimeStr = map.get("watchTime");
                Long watchTimeNew = Long.parseLong(watchTimeStr) + watchTime;
                map.put("watchTime", watchTimeNew.toString());
            }
        }
        Map<String, Map<String, Object>> resultMap = new HashMap();
        Calendar currDayCal = Calendar.getInstance();
        DateTime currDay = DateUtil.endOfWeek(currDayCal.getTime());
        currDayCal.setTime(currDay);
        currDayCal.add(Calendar.DAY_OF_MONTH, 1);
        Calendar weekTreeDay = Calendar.getInstance();
        weekTreeDay.setTime(weekStartTime);
        while (!DateUtil.isSameDay(weekTreeDay.getTime(), currDayCal.getTime())) {
            Date time = weekTreeDay.getTime();
            Integer weekNum = DateUtil.weekOfYear(time);
            String timeSort = simpleDateFormat.format(time);
            if (resultMap.get(weekNum.toString()) == null) {
                Map<String, String> stringStringMap = mapDay.get(timeSort);
                String num = "0";
                if (stringStringMap != null) {
                    num = stringStringMap.get("watchTime");
                }
                List<Integer> dataList = new ArrayList<>();
                dataList.add(Integer.parseInt(num) / (1000 * 60));
                Map<String, Object> map = new HashMap();
                map.put("name", weekNum);
                map.put("type", "bar");
                map.put("data", dataList);
                resultMap.put(weekNum.toString(), map);
            } else {
                Map<String, String> stringStringMap = mapDay.get(timeSort);
                String num = "0";
                if (stringStringMap != null) {
                    num = stringStringMap.get("watchTime");
                }
                Map<String, Object> map = resultMap.get(weekNum.toString());
                List dataList = (List) map.get("data");
                dataList.add(Integer.parseInt(num) / (1000 * 60));
            }
            weekTreeDay.add(Calendar.DAY_OF_MONTH, 1);
        }
        Map mapDate = new HashMap();
        List<String> legendData = new ArrayList<>();
        List<Map<String, Object>> seriesData = new ArrayList<>();
        for (Map.Entry<String, Map<String, Object>> vo : resultMap.entrySet()) {
            legendData.add(vo.getKey());
            seriesData.add(vo.getValue());
        }
        List<String> xAxisData = new ArrayList<>();
        xAxisData.add("周一");
        xAxisData.add("周二");
        xAxisData.add("周三");
        xAxisData.add("周四");
        xAxisData.add("周五");
        xAxisData.add("周六");
        xAxisData.add("周七");
        mapDate.put("legendData", legendData);
        mapDate.put("seriesData", seriesData);
        mapDate.put("xAxisData", xAxisData);
        return mapDate;
    }

    @Override
    public Map<String, Object> monthWatchTime() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat simpleDateFormatYear = new SimpleDateFormat("yyyy");
        Long userId = SecurityContextHolder.getUserId();
        Calendar cal = Calendar.getInstance();
        Integer currYear = cal.get(Calendar.YEAR);
        cal.add(Calendar.YEAR, -2);
        Date startTime = cal.getTime();
        String yearStr = simpleDateFormatYear.format(startTime);
        Map<String, Map<String, String>> mapDay = new HashMap<>();
        List<SysUserStudyTime> sysUserStudyTimeList = sysUserStudyTimeService.list(new QueryWrapper<SysUserStudyTime>().eq("user_id", userId).apply(" date_format( start_time ,'%Y' ) >='" + yearStr + "'"));
        for (SysUserStudyTime vo : sysUserStudyTimeList) {
            Date startTime1 = vo.getStartTime();
            Date endTime = vo.getEndTime();
            String startTimeStr = simpleDateFormat.format(startTime1);
            Long watchTime = (endTime.getTime() - startTime1.getTime());
            if (mapDay.get(startTimeStr) == null) {
                Map<String, String> map = new HashMap<>();
                map.put("day", startTimeStr);
                map.put("watchTime", watchTime.toString());
                mapDay.put(startTimeStr, map);
            } else {
                Map<String, String> map = mapDay.get(startTimeStr);
                String watchTimeStr = map.get("watchTime");
                Long watchTimeNew = Long.parseLong(watchTimeStr) + watchTime;
                map.put("watchTime", watchTimeNew.toString());
            }
        }
        Map<String, Map<String, Object>> resultMap = new HashMap();
        cal.set(Calendar.MONTH, 0);
        while (cal.get(Calendar.YEAR) <= currYear && cal.get(Calendar.MONTH) < 12) {
            Date time = cal.getTime();
            String timeYearSort = simpleDateFormatYear.format(time);
            String timeSort = simpleDateFormat.format(time);
            if (resultMap.get(timeYearSort) == null) {
                Map<String, String> stringStringMap = mapDay.get(timeSort);
                String num = "0";
                if (stringStringMap != null) {
                    num = stringStringMap.get("watchTime");
                }
                List<Integer> dataList = new ArrayList<>();
                dataList.add(Integer.parseInt(num) / (1000 * 60 * 60));
                Map<String, Object> map = new HashMap();
                map.put("name", timeYearSort);
                map.put("type", "bar");
                map.put("data", dataList);
                resultMap.put(timeYearSort, map);
            } else {
                Map<String, String> stringStringMap = mapDay.get(timeSort);
                String num = "0";
                if (stringStringMap != null) {
                    num = stringStringMap.get("watchTime");
                }
                Map<String, Object> map = resultMap.get(timeYearSort);
                List dataList = (List) map.get("data");
                dataList.add(Integer.parseInt(num) / (1000 * 60 * 60));
            }
            cal.add(Calendar.MONTH, 1);
        }
        Map mapDate = new HashMap();
        List<String> legendData = new ArrayList<>();
        List<Map<String, Object>> seriesData = new ArrayList<>();
        for (Map.Entry<String, Map<String, Object>> vo : resultMap.entrySet()) {
            legendData.add(vo.getKey());
            seriesData.add(vo.getValue());
        }

        List<String> xAxisData = new ArrayList<>();
        xAxisData.add("一月");
        xAxisData.add("二月");
        xAxisData.add("三月");
        xAxisData.add("四月");
        xAxisData.add("五月");
        xAxisData.add("六月");
        xAxisData.add("七月");
        xAxisData.add("八月");
        xAxisData.add("九月");
        xAxisData.add("十月");
        xAxisData.add("十一月");
        xAxisData.add("十二月");
        mapDate.put("legendData", legendData);
        mapDate.put("seriesData", seriesData);
        mapDate.put("xAxisData", xAxisData);
        return mapDate;
    }

    @Override
    public Map<String, String> textDescription() {
        Date date = new Date();
        SimpleDateFormat simpleDateFormatYear = new SimpleDateFormat("yyyy");
        SimpleDateFormat simpleDateFormatMonth = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat simpleDateFormatDay = new SimpleDateFormat("yyyy-MM-dd");
        Long userId = SecurityContextHolder.getUserId();
        String currDateYear = simpleDateFormatYear.format(date);
        String currDateMonth = simpleDateFormatMonth.format(date);
        String currDateDay = simpleDateFormatDay.format(date);
        Map yearNumMap = sysUserStudyTimeService.getMap(new QueryWrapper<SysUserStudyTime>().select("sum( UNIX_TIMESTAMP(  sys_user_study_time.end_time) -UNIX_TIMESTAMP(  sys_user_study_time.start_time))/(60*60) as watchTime").eq("user_id", userId).apply(" date_format( start_time ,'%Y' )='" + currDateYear + "'"));
        Map monthNumMap = sysUserStudyTimeService.getMap(new QueryWrapper<SysUserStudyTime>().select("sum( UNIX_TIMESTAMP(  sys_user_study_time.end_time) -UNIX_TIMESTAMP(  sys_user_study_time.start_time))/(60*60) as watchTime").eq("user_id", userId).apply(" date_format( start_time ,'%Y-%m' )='" + currDateMonth + "'"));
        Map dayNumMap = sysUserStudyTimeService.getMap(new QueryWrapper<SysUserStudyTime>().select("sum( UNIX_TIMESTAMP(  sys_user_study_time.end_time) -UNIX_TIMESTAMP(  sys_user_study_time.start_time))/(60) as watchTime").eq("user_id", userId).apply(" date_format( start_time ,'%Y-%m-%d' )='" + currDateDay + "'"));
        DateTime weekStartTime = DateUtil.beginOfWeek(date);
        DateTime weekEndTime = DateUtil.endOfWeek(date);
        String weekStartTimeStr = simpleDateFormatDay.format(weekStartTime);
        String weekEndTimeStr = simpleDateFormatDay.format(weekEndTime);
        Map weeNumMap = sysUserStudyTimeService.getMap(new QueryWrapper<SysUserStudyTime>().select("sum( UNIX_TIMESTAMP(  sys_user_study_time.end_time) -UNIX_TIMESTAMP(  sys_user_study_time.start_time))/(60) as watchTime").eq("user_id", userId).apply(" date_format( start_time ,'%Y-%m-%d' ) >='" + weekStartTimeStr + "'").apply(" date_format( start_time ,'%Y-%m-%d' ) <='" + weekEndTimeStr + "'"));
        Map<String, String> map = new HashMap();
        Object watchTimeYear = yearNumMap.get("watchTime");
        BigDecimal bigDecimalYear = new BigDecimal(0);
        if (watchTimeYear != null) {
            bigDecimalYear = new BigDecimal(watchTimeYear.toString());
            bigDecimalYear = bigDecimalYear.setScale(2, RoundingMode.HALF_UP);
        }
        Object watchTimeMonth = monthNumMap.get("watchTime");
        BigDecimal bigDecimalMonth = new BigDecimal(0);
        if (watchTimeMonth != null) {
            bigDecimalMonth = new BigDecimal(watchTimeMonth.toString());
            bigDecimalMonth = bigDecimalMonth.setScale(2, RoundingMode.HALF_UP);
        }
        BigDecimal bigDecimalWeek = new BigDecimal(0);
        if (weeNumMap != null) {
            Object watchTimeWeek = weeNumMap.get("watchTime");
            bigDecimalWeek = new BigDecimal(watchTimeWeek.toString());
            bigDecimalWeek = bigDecimalWeek.setScale(0);
        }
        BigDecimal bigDecimalDay = new BigDecimal(0);
        if (dayNumMap != null) {
            Object watchTimeDay = dayNumMap.get("watchTime");
            bigDecimalDay = new BigDecimal(watchTimeDay.toString());
            bigDecimalDay = bigDecimalDay.setScale(0);
        }
        map.put("year", bigDecimalYear.toString());
        map.put("month", bigDecimalMonth.toString());
        map.put("week", bigDecimalWeek.toString());
        map.put("day", bigDecimalDay.toString());
        return map;
    }

    @Override
    public Map<String, Object> lastThreeYear() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
        Long userId = SecurityContextHolder.getUserId();
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.YEAR, -2);
        Date startTime = cal.getTime();
        String startStr = simpleDateFormat.format(startTime);
        Map<String, Map<String, String>> mapDay = new HashMap<>();
        List<SysUserStudyTime> sysUserStudyTimeList = sysUserStudyTimeService.list(new QueryWrapper<SysUserStudyTime>().eq("user_id", userId).apply(" date_format( start_time ,'%Y' ) >='" + startStr + "'"));
        for (SysUserStudyTime vo : sysUserStudyTimeList) {
            Date startTime1 = vo.getStartTime();
            Date endTime = vo.getEndTime();
            String startTimeStr = simpleDateFormat.format(startTime1);
            Long watchTime = (endTime.getTime() - startTime1.getTime()) / (1000 * 60);
            if (mapDay.get(startTimeStr) == null) {
                Map<String, String> map = new HashMap<>();
                map.put("day", startTimeStr);
                map.put("watchTime", watchTime.toString());
                mapDay.put(startTimeStr, map);
            } else {
                Map<String, String> map = mapDay.get(startTimeStr);
                String watchTimeStr = map.get("watchTime");
                Long watchTimeNew = Long.parseLong(watchTimeStr) + watchTime;
                map.put("watchTime", watchTimeNew.toString());
            }
        }
        List<String> xAxisData = new ArrayList<>();
        List<String> seriesData = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap();
        for (int i = 0; i < 3; i++) {
            Date time = cal.getTime();
            String timeSort = simpleDateFormat.format(time);
            Map<String, String> stringStringMap = mapDay.get(timeSort);
            String num = "0";
            if (stringStringMap != null) {
                num = stringStringMap.get("watchTime");
            }
            Integer numMin = Integer.parseInt(num) / 60;
            seriesData.add(numMin.toString());
            xAxisData.add(timeSort);
            cal.add(Calendar.YEAR, 1);
        }
        resultMap.put("xAxis", xAxisData);
        resultMap.put("series", seriesData);
        return resultMap;
    }

    @Override
    public void updateSysUserStudyTime(SysUserStudyTimeVo sysUserStudyTimeVo) {
        SysUserStudyTime sysUserStudyTime = new SysUserStudyTime();
        BeanUtils.copyProperties(sysUserStudyTimeVo, sysUserStudyTime);
        sysUserStudyTimeService.updateById(sysUserStudyTime);
    }
}




